package org.sixtynine.stock.controller;

import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Restrictions;
import org.sixtynine.stock.dto.GridPramDTO;
import org.sixtynine.stock.dto.Page;
import org.sixtynine.stock.entity.BaseEntity;
import org.sixtynine.stock.entity.MonthlySectorData;
import org.sixtynine.stock.model.FileUploadForm;
import org.sixtynine.stock.model.LoadingSearchCriteria;
import org.sixtynine.stock.service.GenericService;
import org.sixtynine.stock.service.MonthlySectorDataService;
import org.sixtynine.stock.service.content.DataManagerService;
import org.sixtynine.stock.service.file.ExcelProcessorFactory;
import org.sixtynine.stock.service.file.FileDataService;
import org.sixtynine.stock.util.DateUtil;
import org.sixtynine.stock.util.SessionBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.servlet.ModelAndView;

/**
 * @author Thilan this class handle monthly sector data
 */

@Controller
@SessionAttributes
public class MonthlySectorController extends SectorDataController {

	@Autowired
	private GenericService genericService;

	@Autowired
	private FileDataService fileDataService;

	@Autowired
	DataManagerService dataManagerService;

	@Autowired
	private MonthlySectorDataService monthlySectorDataService;

	private static final String BIND_VAL_MONTHLY_SECTOR_DATA = "monthlySectorData";

	@RequestMapping(value = "/admin/monthlysectordata/search")
	public ModelAndView search(@ModelAttribute LoadingSearchCriteria criteria,
			HttpServletRequest request) {
		return search(criteria, request);
	}

	@RequestMapping(value = "/admin/monthlysectordata/add")
	public ModelAndView addMonthlySectorData(HttpServletRequest request) {

		ModelAndView modelAndView = new ModelAndView(getAddPage());

		bindDummyObject(modelAndView);
		bindSectorList(modelAndView);
		bindFileUpload(modelAndView);

		return modelAndView;
	}

	@RequestMapping(value = "/admin/monthlysectordata/add/file_process")
	public ModelAndView addingCompaniesByFile(HttpServletRequest request,
			@ModelAttribute("uploadFile") FileUploadForm uploadFile) {
		return addSectorDataByFile(request, uploadFile);
	}

	@RequestMapping(value = "/admin/monthlysectordata/add/sector_process")
	public ModelAndView addingSectorsByFile(
			@ModelAttribute("uploadFile") FileUploadForm uploadFile) {
		return processSectorDataBySector(uploadFile);
	}

	@RequestMapping(value = "/admin/monthlysectordata/add/process")
	public ModelAndView addingMonthlySectorData(
			@ModelAttribute MonthlySectorData monthlySectorData,
			BindingResult result) {
		ModelAndView modelAndView = null;

		if (monthlySectorData.getDate() == null) {
			modelAndView = new ModelAndView(getAddPage());
			String message = "The date cannot be empty, Please enter a correct date.";
			modelAndView.addObject(BIND_VAL_MESSAGE, message);
			return modelAndView;
		}

		// check future dates
		if (DateUtil.checkFutureDate(monthlySectorData.getDate())) {
			modelAndView = new ModelAndView(getAddPage());
			String message = "You can't add a future date. Please enter a current or past record.";
			modelAndView.addObject(BIND_VAL_MESSAGE, message);
			return modelAndView;
		}

		// check data is already exists or not
		Criterion compleateCriterion = Restrictions.between("date", DateUtil
				.getMonthStart(DateUtil.getMonthFromDate(monthlySectorData
						.getDate())), DateUtil.getMonthEnd(DateUtil
				.getMonthFromDate(monthlySectorData.getDate())));

		List<BaseEntity> dataList = genericService.findByCriteria(
				compleateCriterion, MonthlySectorData.class);
		if (dataList.size() > 0) {
			modelAndView = new ModelAndView(getAddPage());
			String message = "Data already exists for ."
					+ monthlySectorData.getDate();
			modelAndView.addObject(BIND_VAL_MESSAGE, message);

			loadData(1, -1, monthlySectorData.getSector().getId(), null,
					monthlySectorData.getDate(), monthlySectorData.getDate(),
					modelAndView, null);
			return modelAndView;
		}

		if (!result.hasErrors()) {
			genericService.saveOrUpdate(monthlySectorData);
			modelAndView = new ModelAndView(getPage());

			String message = "Data is successfully inserted.";
			modelAndView.addObject(BIND_VAL_MESSAGE, message);

			loadData(1, -1, monthlySectorData.getSector().getId(), null,
					monthlySectorData.getDate(), monthlySectorData.getDate(),
					modelAndView, null);
		} else {
			modelAndView = new ModelAndView(getAddPage());
			bindDummyObject(modelAndView);
			bindSectorList(modelAndView);
			bindFileUpload(modelAndView);
		}

		return modelAndView;
	}

	@RequestMapping(value = "/admin/monthlysectordata/list")
	public ModelAndView listOfMonthlySectorData(
			HttpServletRequest request,
			@RequestParam(value = "page", required = false) Integer page,
			@RequestParam(value = "totalRecords", required = false) Integer totalRecords) {
		return showList(request, page, totalRecords);
	}

	@RequestMapping(value = "/admin/monthlysectordata/edit/{id}", method = RequestMethod.GET)
	public ModelAndView editMonthlySectorData(HttpServletRequest request,
			@PathVariable Integer id) {
		return showEdit(id);
	}

	@RequestMapping(value = "/admin/monthlysectordata/edit/{id}", method = RequestMethod.POST)
	public ModelAndView edditingMonthlySectorData(
			@ModelAttribute MonthlySectorData monthlySectorData,
			BindingResult result, @PathVariable Integer id) {
		return editSectorData(monthlySectorData, result);
	}

	@RequestMapping(value = "/admin/monthlysectordata/delete/{id}", method = RequestMethod.GET)
	public ModelAndView deleteMonthlySectorData(@PathVariable Integer id) {
		return deleteSectorData(id);
	}

	@RequestMapping(value = "/admin/monthlysectordata/delete/selected")
	public ModelAndView deleteSelectedMonthlySectorData(
			HttpServletRequest request,
			@RequestParam(value = "deleteIds", required = false) Integer[] deleteIds) {
		return deleteSelected(deleteIds);
	}

	@RequestMapping(value = "/admin/monthlysectordata/deleteFiltered")
	public ModelAndView deleteFilteredMonthlySectorData(
			HttpServletRequest request) {
		ModelAndView modelAndView = new ModelAndView(getPage());

		SessionBean sBean = SessionBean.getInstance(request);
		LoadingSearchCriteria criteria = (LoadingSearchCriteria) sBean
				.getAttr(SEARCH_CRITERIA);
		if (criteria == null) {
			criteria = new LoadingSearchCriteria();
		}
		// delete the selected criteria
		monthlySectorDataService.deleteMonthlySectorData(
				criteria.getSectorId(), criteria.getFromDate(),
				criteria.getToDate());

		// reload the page
		loadData(1, -1, criteria.getSectorId(), null, criteria.getFromDate(),
				criteria.getToDate(), modelAndView, criteria);

		return modelAndView;
	}

	@Override
	protected Class getBaseClass() {
		return MonthlySectorData.class;
	}

	@Override
	protected String getPage() {
		return "/admin/monthlysectordata/list";
	}

	@Override
	protected void setPageData(int sectorId, Date fromDate, Date toDate,
			String sortByFirst, String sortBySecond, GridPramDTO gridPramDTO,
			ModelAndView modelAndView) {

		Page<MonthlySectorData> monthlySectorDataPage = monthlySectorDataService
				.searchMonthlySectorData(sectorId, fromDate, toDate, null,
						null, gridPramDTO);
		modelAndView.addObject("monthlySectorDataPage", monthlySectorDataPage);

	}

	@Override
	protected String getEditPage() {
		return "/admin/monthlysectordata/edit";
	}

	@Override
	protected void loadData(Integer page, Integer totalRecords,
			BaseEntity shareData, ModelAndView modelAndView,
			LoadingSearchCriteria criteria) {
		MonthlySectorData monthlySectorData = (MonthlySectorData) shareData;
		loadData(page, totalRecords, monthlySectorData.getSector().getId(),
				null, monthlySectorData.getDate(), monthlySectorData.getDate(),
				modelAndView, criteria);

	}

	@Override
	protected String getObjBindName() {
		return "monthlySectorData";
	}

	@Override
	protected String getAddPage() {
		return "/admin/monthlysectordata/add";
	}

	@Override
	protected String getExelProcessorType() {
		return ExcelProcessorFactory.FILE_TYPE_MONTHLY_SECTOR_DATA_LIST;
	}

	@Override
	protected String getSectorExcelProcessorType() {
		return ExcelProcessorFactory.FILE_TYPE_SECTOR_MONTHLY_DATA_LIST;
	}

	@Override
	protected void bindFileUpload(ModelAndView modelAndView) {
		modelAndView.addObject(BIND_VAL_FILE_UPLOAD, new FileUploadForm());
	}

	@Override
	protected void bindDummyObject(ModelAndView modelAndView) {
		modelAndView.addObject(BIND_VAL_MONTHLY_SECTOR_DATA,
				new MonthlySectorData());
	}

}
